import os
import random
import cv2 as cv
import math
import numpy as np
from matplotlib import pyplot


# def read_img(img_path):
#     """
#     读取图像，返回图像矩阵
#     """
#     src_img = cv.imread(img_path, cv.IMREAD_GRAYSCALE)
#     print("图像的高为:%s,图像的宽为:%s" % (src_img.shape[0], src_img.shape[1]))
#     # cv.namedWindow("src_img", cv.WINDOW_AUTOSIZE)
#     # cv.imshow("src_img", src_img)
#     # cv.waitKey(3000)
#     # cv.destroyAllWindows()
#     return src_img


def CallFunctionMeanFiltering(src_img):
    """
    调用opencv函数实现均值滤波，函数参数为imread()函数读取出的图像矩阵
    """
    kernel = input("输入核的大小")
    kernel = int(kernel)
    ret = cv.blur(src_img, (kernel, kernel))
    cv.imshow("src:", src_img)
    cv.imshow("after", ret)
    cv.waitKey()
    cv.destroyAllWindows()


def CallFunctionBoxFilter(src_img):
    """
    调用opencv函数实现方框滤波，函数参数为imread()函数读取出的图像矩阵
    处理结果 = cv2.boxFilter(原始图像， 目标图像深度， 核大小， normsize属性)
    normsizes属性：是否对目标图像进行归一化处理,如果进行归一化处理，和均值滤波效果一样
    如果不进行归一化处理，可能发生溢出，全白图像
    """
    ret = cv.boxFilter(src_img, -1, (3, 3), normalize=1)
    cv.imshow("ret", ret)
    cv.waitKey()
    cv.destroyAllWindows()


def CallFunctionGaussianFilter(src_img):
    """
    调用函数实现高斯滤波，计算加权平均，参数为读取出的图像矩阵
    dst = cv2.GaussianBlur(src, ksize, sigmaX)
    src:愿图像 kisze:核大小，必须是奇数 sigmaX:X方向的方差
    """
    ret = cv.GaussianBlur(src_img, (3, 3), 0)


def CallFunctionMedianFiltering(src_img):
    """
    调用函数实现中值滤波，函数参数为图像矩阵
    ret = cv.medianBlur(src, ksize)
    src:原图像 ksize:核大小
    """
    ret = cv.medianBlur(src_img, (3, 3))


def integral(image):
    rows, cols = image.shape
    # 行积分运算
    inteImageC = np.zeros((rows, cols), np.float32)
    for r in range(rows):
        for c in range(cols):
            if c == 0:
                inteImageC[r][c] = image[r][c]
            else:
                inteImageC[r][c] = inteImageC[r][c-1] + image[r][c]
    # 列积分运算
    inteImage = np.zeros(image.shape, np.float32)
    for c in range(cols):
        for r in range(rows):
            if r == 0:
                inteImage[r][c] = inteImageC[r][c]
            else:
                inteImage[r][c] = inteImage[r-1][c] + inteImageC[r][c]
    inteImage_0 = np.zeros((rows+1, cols+1), np.float32)
    inteImage_0[1:rows+1, 1:cols+1] = inteImage
    return inteImage_0


def fastMeanBlur(image, winSize, borderType = cv.BORDER_DEFAULT):
    halfH = (winSize[0]-1)/2
    halfW = (winSize[1]-1)/2
    ratio = 1.0/(winSize[0]*winSize[1])
    paddImage = cv.copyMakeBorder(image, halfH, halfH, halfW, halfW, borderType)
    # paddImage = paddImage.astype(np.uint8)
    paddIntegral = integral(paddImage)
    rows, cols = image.shape
    meanBlurImage = np.zeros(image.shape, np.float32)
    r, c = 0, 0
    for h in range(halfH, halfH+rows, 1):
        for w in range(halfW, halfW+cols, 1):
            meanBlurImage[r][c] = (paddIntegral[h+halfH+1][w+halfW+1]+paddIntegral[h-halfH][w-halfW]-paddIntegral[h+halfH+1][w-halfW]-paddIntegral[h-halfH][w+halfW+1])*ratio
            c += 1
        r += 1
        c = 0
    return meanBlurImage


def salt(image, number):
    rows, cols = image.shape
    saltImage = np.copy(image)
    for i in range(number):
        randR = random.randint(0, rows-1)
        randC = random.randint(0, cols-1)
        saltImage[randR][randC] = 255
    return saltImage


def medianBlur(image, winSize):
    rows, cols = image.shape
    winH, winW = winSize
    halfWinH = (winH-1)//2
    halfWinW = (winW-1)//2
    medianBlurImage = np.zeros(image.shape, image.dtype)
    for r in range(rows):
        for c in range(cols):
            rTop = 0 if r-halfWinH < 0 else r-halfWinH
            rBottom = rows-1 if r+halfWinH > rows-1 else r+halfWinH
            cLeft = 0 if c - halfWinW < 0 else c-halfWinW
            cRight = cols-1 if c+halfWinW > cols-1 else c+halfWinW
            region = image[rTop:rBottom+1, cLeft:cRight+1]
            medianBlurImage[r][c] = np.median(region)
    return medianBlurImage


# 频率滤波 1.理想低通滤波器 2.巴特沃斯低通滤波器 3.高斯低通滤波器

if __name__ == "__main__":
    pinghua_path = "./img/pinghua/danghui_yuantu.bmp"
    src = cv.imread(pinghua_path, cv.IMREAD_GRAYSCALE)
    # src = read_img(pinghua_path)
    # ret = cv.blur(src, (3, 3))
    # CallFunctionMeanFiltering(src)
    # ret = fastMeanBlur(src, (3, 3))
    ret = salt(src, 10000)
    after = medianBlur(ret, (9, 9))
    cv.imshow("ret", ret)
    cv.imshow("after", after)
    cv.waitKey()
    cv.destroyAllWindows()

